package behaviourNavigatore;

import java.awt.Dimension;
import java.nio.file.AccessMode;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import navigatore.AgenteNavigatore;

import org.jgrapht.Graph;
import org.jgrapht.graph.Subgraph;

import com.sun.org.apache.xpath.internal.axes.MatchPatternIterator;

import utility.Auto;
import utility.MyDefaultWeightedEdge;
import utility.Triple;
import jade.core.AID;
import jade.core.behaviours.Behaviour;
import jade.core.behaviours.CyclicBehaviour;
import jade.core.behaviours.OneShotBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

public class BargainingStreets extends Behaviour {

	private static final long serialVersionUID = 1L;

	private AgenteNavigatore navigatore;

	private Set<Triple<Dimension, String, String>> newSetBridge;

	private MessageTemplate mt;
	private ACLMessage msg;
	private Step step = Step.INIT;
	int numMsg = 0;

	int migliorNavigatore = -1;
	int migliorCarico = 1000000;;
	int timeout = 0;


	boolean ciclo = false, busy=false;

	private enum Step {INIT, RICHIESTA_AIUTO, PROCESSA_RICHIESTA_AIUTO, ASPETTA_RISPOSTA,INVIO_CONFERMA_AIUTO,ASPETTA_CONFERMA_FINALE,
		RICHIESTA_RIPRISTINO, WAIT_CONFERMA_RIPRISTINO, EXIT};

	@Override
	public void action() {
		// TODO Auto-generated method stub
		navigatore = (AgenteNavigatore)myAgent;

//RICORDARSI DELLA LISTA DEI NAV AIUTANTIIIIIIIIIIIIIIIIII
		switch (step) {

		case INIT:

			// dobbiamo impedire che tutti e due i navigatori chiedano aiuto contemporaneanete!!!!!!!!

			timeout = 0;

			//CHIEDO FINE AIUTO
			if(navigatore.isHelped() && navigatore.getNumAutoNavigatore() == 0) {
				System.out.println(navigatore.getAID().getName()+" CHIEDE IL RIPRISTINO");
				
				int idNav = navigatore.getListaNavigatoriAiutanti().get(0);
				
				ACLMessage messaggio = new ACLMessage(ACLMessage.PROPOSE);
				messaggio.setLanguage("Italiano");
				messaggio.setSender(myAgent.getAID());
				messaggio.addReceiver(new AID("navigatore"+idNav,AID.ISLOCALNAME));
				myAgent.send(messaggio);
				
				mt = MessageTemplate.or(MessageTemplate.MatchPerformative(ACLMessage.REJECT_PROPOSAL), 
						MessageTemplate.MatchPerformative(ACLMessage.ACCEPT_PROPOSAL));
				
				step = Step.WAIT_CONFERMA_RIPRISTINO;
				
				break;
			}
			
			else if(navigatore.isHelping()) {

				mt = MessageTemplate.MatchPerformative(ACLMessage.PROPOSE);
				
				ACLMessage msgFinishHelp = myAgent.receive(mt);
				
				if(msgFinishHelp != null) {

					if(navigatore.getNumAutoNavigatore() > 0) {
						
						System.out.println(myAgent.getLocalName()+"   NON POSSO RIPRISTINARE SONO ANCORA OCCUPATO");
						
						ACLMessage replyFinish = msgFinishHelp.createReply();
						replyFinish.setPerformative( ACLMessage.REJECT_PROPOSAL);
						myAgent.send(replyFinish);
					}
					
					else {
						
						int idNav = Integer.parseInt(msgFinishHelp.getSender().getLocalName().substring(10, myAgent.getLocalName().length()));
						
						ACLMessage replyFinish = msgFinishHelp.createReply();
						replyFinish.setPerformative( ACLMessage.ACCEPT_PROPOSAL);
						myAgent.send(replyFinish);
						
						System.out.println(myAgent.getLocalName()+"   AVVIO PROCEDURE DI RIPRISTINO  ************");
						
//						String myId = myAgent.getLocalName().substring(10, myAgent.getLocalName().length());
//						refreshNavigatoreAiutanteStructures(idNav+"", myId);
						refreshNavigatoreHelpedStructures(idNav+"");
						
						for (int i = 0; i < navigatore.getListaNavigatoriAiutanti().size(); i++) {
							if(navigatore.getListaNavigatoriAiutati().get(i) == idNav) {
								navigatore.getListaNavigatoriAiutati().remove(i);
								break;
							}
						}
						
						if(navigatore.getListaNavigatoriAiutati().isEmpty())
							navigatore.setHelping(false);
						
						navigatore.getListaNavigatoriAssociati().add(idNav);
						
						step = Step.EXIT;
						
						
						
						Set<MyDefaultWeightedEdge> subedge = navigatore.getSubGraph().edgeSet();
						
						
						
						for (MyDefaultWeightedEdge edge : subedge) {
							System.out.println(navigatore.getSubGraph().getEdgeSource(edge)+"  ----------   "+navigatore.getSubGraph().getEdgeTarget(edge));
						}
						
						for (Triple<Dimension, String, String> triple : navigatore.getBridgeSource()) {
							System.out.println("source  bridge"+triple);
						}
						
						for (Triple<Dimension, String, String> triple : navigatore.getBridgeTarget()) {
							System.out.println("target  bridge"+triple);
						}
						
//						myAgent.doSuspend();

						
						break;
						
					}
				}
			}
			
			if(navigatore.getListaNavigatoriAssociati().size() > 0) 
			{
				double index = (double)(navigatore.getNumAutoNavigatore()*2)/navigatore.getMaxNumAutoNavigatore();
				
//				System.out.println("INDEXXXXXXXX   "+ index);
				
				if(index >= 0.2 && !navigatore.isHelping()) {// && myAgent.getAID().getLocalName().equals("navigatore1") ){
					System.out.println("$$$$$$$$$$"+navigatore.getAID().getName()+" HELP!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
					step = Step.RICHIESTA_AIUTO;
				}
				else 
				{
					mt = MessageTemplate.and(MessageTemplate.MatchPerformative(ACLMessage.REQUEST), 
							MessageTemplate.MatchConversationId("requestHelp"));
					step = Step.PROCESSA_RICHIESTA_AIUTO;
				}

			}
			
			else
				step = Step.EXIT;
			
			break;

		case WAIT_CONFERMA_RIPRISTINO:
			
			ACLMessage msgWait = myAgent.receive(mt);
			
			if(msgWait != null) {
				
				if(msgWait.getPerformative() == ACLMessage.REJECT_PROPOSAL) {
					
					System.out.println(myAgent.getLocalName()+"   PROPOSTA DI RIPRISTINO RIFIUTATA");
					
					step = Step.EXIT;
				}
				
				else if(msgWait.getPerformative() == ACLMessage.ACCEPT_PROPOSAL) {
					
					System.out.println(myAgent.getLocalName()+"   RIPRISTINO CONFIGURAZIONE ***************");
					
					int idNav = Integer.parseInt(msgWait.getSender().getLocalName().substring(10, myAgent.getLocalName().length()));
					String myId = myAgent.getLocalName().substring(10, myAgent.getLocalName().length());
					
					
					//System.out.println("BEFOREEEEEEEEEEEEEEEE");
					
					for (Triple<Dimension, String, String> triple : navigatore.getBridgeSource()) {
						System.out.println("source  bridge"+triple);
					}
					
					for (Triple<Dimension, String, String> triple : navigatore.getBridgeTarget()) {
						System.out.println("target  bridge"+triple);
					}
					
//					refreshNavigatoreHelpedStructures(idNav+"");
					refreshNavigatoreAiutanteStructures(idNav+"", myId);
					
					navigatore.getListaNavigatoriAssociati().add(idNav);
					
					//rimuovo il navigatore tra gli aiutati
//					for (int i = 0; i < navigatore.getListaNavigatoriAiutanti().size(); i++) {
//						if(navigatore.getListaNavigatoriAiutanti().get(i) == idNav) {
//							navigatore.getListaNavigatoriAiutanti().remove(i);
//							break;
//						}
//					}
					
					navigatore.getListaNavigatoriAiutanti().remove(0);
					
					if(navigatore.getListaNavigatoriAiutanti().isEmpty())
						navigatore.setHelped(false);
					
					
					Set<MyDefaultWeightedEdge> subedge = navigatore.getSubGraph().edgeSet();
					
					for (MyDefaultWeightedEdge edge : subedge) {
						System.out.println(navigatore.getSubGraph().getEdgeSource(edge)+"  ----------   "+navigatore.getSubGraph().getEdgeTarget(edge));
					}
					
					for (Triple<Dimension, String, String> triple : navigatore.getBridgeSource()) {
						System.out.println("source  bridge"+triple);
					}
					
					for (Triple<Dimension, String, String> triple : navigatore.getBridgeTarget()) {
						System.out.println("target  bridge"+triple);
					}
//					myAgent.doSuspend();
					
					step = Step.EXIT;
				}
				
				break;
			}
			
			else {
				block(100);
				timeout++;
				if(timeout >= 20) {
					System.out.println("TIME OUT");
					timeout = 0;
					step = Step.EXIT;
				}
				System.out.println(myAgent.getLocalName()+"   messaggio ripristino nn arrivato");
				break;
			}
			
		case RICHIESTA_AIUTO:

			System.out.println(myAgent.getLocalName()+ "   richiede aiuto");
			numMsg = navigatore.getListaNavigatoriAssociati().size();

			for (int i = 0; i < numMsg; i++) {

				int idNav = navigatore.getListaNavigatoriAssociati().get(i);

				ACLMessage messaggio = new ACLMessage(ACLMessage.REQUEST);
				messaggio.setLanguage("Italiano");
				messaggio.setConversationId("requestHelp");
				messaggio.setSender(myAgent.getAID());
				messaggio.addReceiver(new AID("navigatore"+idNav,AID.ISLOCALNAME));
				myAgent.send(messaggio);
			}


			mt = MessageTemplate.or(MessageTemplate.or(MessageTemplate.MatchPerformative(ACLMessage.REJECT_PROPOSAL), 
					MessageTemplate.MatchPerformative(ACLMessage.ACCEPT_PROPOSAL)), MessageTemplate.MatchPerformative(ACLMessage.REQUEST));

			step = Step.ASPETTA_RISPOSTA; 
			break;



		case PROCESSA_RICHIESTA_AIUTO:

			System.out.println(myAgent.getLocalName()+"   processa la richiesta dell'altro navigatore");

			ACLMessage msg2 = myAgent.receive(mt);

			if(msg2 != null) {

				if(msg2.getPerformative() == ACLMessage.REQUEST) {

					System.out.println(myAgent.getLocalName()+" PROCESSA_RICHIESTA_AIUTO");

					// da aggiustare ik numero 1000
					if((double)(navigatore.getNumAutoNavigatore()) /navigatore.getMaxNumAutoNavigatore() >= 1000 || navigatore.isHelped()) {
						System.out.println(myAgent.getLocalName()+" proposta rifiutataaaaaaaaaaaaaaaaaaaaa");

						ACLMessage reply = msg2.createReply();
						reply.setPerformative( ACLMessage.REJECT_PROPOSAL);
						myAgent.send(reply);

						String idNav = reply.getSender().getLocalName().substring(10, myAgent.getLocalName().length());

						//elimina l'id nav dalla lista di nav associati
						int id = Integer.parseInt(idNav);
						for (int i = 0; i < navigatore.getListaNavigatoriAssociati().size(); i++) {
							if(navigatore.getListaNavigatoriAssociati().get(i) == id) {
								navigatore.getListaNavigatoriAssociati().remove(i);
								break;
							}

						}

						step = Step.EXIT;
					}

					else {

						int myCarico = navigatore.getNumAutoNavigatore();

						String idNav = myAgent.getLocalName().substring(10, myAgent.getLocalName().length());

						System.out.println(myAgent.getLocalName()+ "  accetta la proposta");
						ACLMessage reply = msg2.createReply();
						reply.setPerformative( ACLMessage.ACCEPT_PROPOSAL);
						reply.setContent(idNav+","+myCarico);
						myAgent.send(reply);

						mt = MessageTemplate.or(MessageTemplate.MatchPerformative(ACLMessage.CONFIRM), MessageTemplate.MatchPerformative(ACLMessage.REFUSE));

						step = Step.INVIO_CONFERMA_AIUTO;

					}

				}
			}

			else{
				step = Step.EXIT;
			}

			break;

		case ASPETTA_RISPOSTA:

			System.out.println(myAgent.getLocalName()+" aspetta risposta");

			ACLMessage msgRisp = myAgent.receive(mt);

			if(msgRisp != null) {

				if(msgRisp.getPerformative() == ACLMessage.REJECT_PROPOSAL || msgRisp.getPerformative() == ACLMessage.REQUEST)
				{

					System.out.println("proposta rigettata");

					String idNav = msgRisp.getSender().getLocalName().substring(10, myAgent.getLocalName().length());

					//elimina l'id nav dalla lista di nav associati
					int id = Integer.parseInt(idNav);
					for (int i = 0; i < navigatore.getListaNavigatoriAssociati().size(); i++) {
						if(navigatore.getListaNavigatoriAssociati().get(i) == id) {
							navigatore.getListaNavigatoriAssociati().remove(i);
							break;
						}

					}

					numMsg--;
				}
				//in quest caso devo avviare le modifiche sui sottografi
				else if(msgRisp.getPerformative() == ACLMessage.ACCEPT_PROPOSAL)
				{

					numMsg--;

//					System.out.println(myAgent.getLocalName()+"   SIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII!!!");

					StringTokenizer st1 = new StringTokenizer(msgRisp.getContent(), ",");
					int idNav = Integer.parseInt(st1.nextToken());
					int carico = Integer.parseInt(st1.nextToken());

					if(carico <= migliorCarico) {

						if(migliorNavigatore != -1) {

							ACLMessage replayMsg2 = new ACLMessage(ACLMessage.REFUSE);
							replayMsg2.setLanguage("Italiano");
							replayMsg2.setSender(myAgent.getAID());
							replayMsg2.addReceiver(new AID("navigatore"+migliorNavigatore, AID.ISLOCALNAME));
							myAgent.send(replayMsg2);
						}

						migliorCarico = carico;
						migliorNavigatore = idNav;
					}

					else  {

						ACLMessage replayMsg2 = new ACLMessage(ACLMessage.REFUSE);
						replayMsg2.setLanguage("Italiano");
						replayMsg2.setSender(myAgent.getAID());
						replayMsg2.addReceiver(new AID(msgRisp.getSender().getLocalName(), AID.ISLOCALNAME));
						myAgent.send(replayMsg2);
					}

				}


			}

			else if(numMsg > 0){

				block(100);
				timeout++;
				if(timeout >= 20) {
					numMsg--;
					System.out.println("TIME OUT");
					timeout = 0;
				}
				System.out.println("ciao");

				break;
			}

			// se sto processando l'ultimo messaggio
			if(numMsg == 0) {
				if(migliorNavigatore == -1)
					step = Step.EXIT;

				else {

					ACLMessage replayMsg2 = new ACLMessage(ACLMessage.CONFIRM);
					replayMsg2.setLanguage("Italiano");
					replayMsg2.setSender(myAgent.getAID());
					replayMsg2.addReceiver(new AID("navigatore"+migliorNavigatore, AID.ISLOCALNAME));
					myAgent.send(replayMsg2);


					mt = MessageTemplate.MatchPerformative(ACLMessage.AGREE);
					step= Step.ASPETTA_CONFERMA_FINALE;
				}
			}

			break;

		case ASPETTA_CONFERMA_FINALE:

			System.out.println(myAgent.getLocalName()+"   aspetto conferma finale");

			ACLMessage msg3 = myAgent.receive(mt);

			if(msg3 != null)
			{

				if(msg3.getPerformative() == ACLMessage.AGREE)
				{
					System.out.println(myAgent.getLocalName()+"   CONFERMA FINALE ARRIVATA STOP DAELL 'AIUTATO!");

					/// MODIFICA LE STRUTTURE **********************************

					String idNav = msg3.getSender().getLocalName().substring(10, myAgent.getLocalName().length());
					refreshNavigatoreHelpedStructures(idNav);

					
					
					//elimina l'id nav dalla lista di nav associati
					int id = Integer.parseInt(idNav);
					for (int i = 0; i < navigatore.getListaNavigatoriAssociati().size(); i++) {
						if(navigatore.getListaNavigatoriAssociati().get(i) == id) {
							navigatore.getListaNavigatoriAssociati().remove(i);
							break;
						}

					}

					//lo aggiungo alla lista di navigatori aiutanti 
					navigatore.getListaNavigatoriAiutanti().add(id);
					
//					System.out.println(myAgent.getLocalName()+"     BREEKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK");


					navigatore.setHelped(true);
					migliorCarico = 1000000;
					migliorNavigatore = -1;


					step = Step.EXIT;
				}

			}

			break;

		case INVIO_CONFERMA_AIUTO:


			System.out.println(myAgent.getLocalName()+"      invia conferma aiuto");
			ACLMessage msgRsp = myAgent.receive(mt);

			if(msgRsp != null)
			{

				if(msgRsp.getPerformative() == ACLMessage.CONFIRM)
				{

					System.out.println("INVIO CONFERMA EFFETTUATO STOP LA CONVERSAZIONE DALL AIUTANTE!!!!");



					String idNav = msgRsp.getSender().getLocalName().substring(10, myAgent.getLocalName().length());
					String myId = myAgent.getLocalName().substring(10, myAgent.getLocalName().length());
					
					refreshNavigatoreAiutanteStructures(idNav, myId);

					//elimina l'id nav dalla lista di nav associati
					int id = Integer.parseInt(idNav);
					for (int i = 0; i < navigatore.getListaNavigatoriAssociati().size(); i++) {
						if(navigatore.getListaNavigatoriAssociati().get(i) == id) {
							navigatore.getListaNavigatoriAssociati().remove(i);
							break;
						}

					}

					//aggiunge l'id alla lista dei navigatori aiutati
					navigatore.getListaNavigatoriAiutati().add(id);
					
//					System.out.println(myAgent.getLocalName()+"     BREEKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK");

					ACLMessage rpl = msgRsp.createReply();
					rpl.setPerformative(ACLMessage.AGREE);
					myAgent.send(rpl);

					navigatore.setHelping(true);
					step = Step.EXIT;

				}

				else if(msgRsp.getPerformative() == ACLMessage.REFUSE)
					step = Step.EXIT;
			}

			break;

		case EXIT:
			System.out.println(myAgent.getLocalName()+"   sono andato in EXIT");
			step = Step.INIT;
			ciclo = true;
			break;

		default:
			break;
		}

		block(500);
	}





	private void refreshNavigatoreAiutanteStructures(String idNav, String myId) {

		Subgraph<Triple<Dimension,String,String>, MyDefaultWeightedEdge, 
		Graph<Triple<Dimension,String,String>,MyDefaultWeightedEdge>> subGraph = navigatore.getSubGraph();

		//lista di nodi ex sorgenti da eliminare
		List<Triple<Dimension, String, String>> bridgeSourceToDelete  = new LinkedList<Triple<Dimension, String, String>>();

		//lista di nodi ex target da eliminare
		List<Triple<Dimension, String, String>> bridgeTargetToDelete  = new LinkedList<Triple<Dimension, String, String>>();
		
		Set<Triple<Dimension, String, String>> setRealTarget  = navigatore.getBroker().getParser().createBridgeTarget(Integer.parseInt(myId));

		for (Triple<Dimension, String, String> oldTarget : navigatore.getBridgeTarget()) {

			if(oldTarget.getThird().equals(idNav)) {

				bridgeTargetToDelete.add(oldTarget);
				
				Triple<Dimension, String, String> realTarget = null;
				
				if(navigatore.isHelped()) {
					 realTarget = new Triple<Dimension, String, String>(oldTarget.getFirst(), oldTarget.getSecond(), myId);
				}
				
				else
					realTarget = oldTarget;
				
				for (Triple<Dimension, String, String> oldSource : navigatore.getBridgeSource()) {
					if(subGraph.containsEdge(realTarget, oldSource)) {
						bridgeSourceToDelete.add(oldSource);

						//aggiungo l'arco mancante al sottografo e le sue relative auto al navigatore
						if(navigatore.getGraph().containsEdge(oldSource, realTarget))  {

							MyDefaultWeightedEdge edge = navigatore.getGraph().getEdge(oldSource, realTarget);

							for (int i = 0; i < edge.getSizeListAuto(); i++) {
								for (int j = 0; j < navigatore.getBroker().getAutoBroker().size(); j++) {
									Auto auto = navigatore.getBroker().getAutoBroker().get(j);
									if(edge.getListIdAuto().get(i) == auto.getId()) {
										navigatore.addAuto(auto);
										break;
									}

								}
							}

							subGraph.addEdge(oldSource, realTarget);
						}
					}
				}

			}
		}

		//elimino i vecchi nodi sorgente
		for (Triple<Dimension, String, String> triple : bridgeSourceToDelete) {
			navigatore.getBridgeSource().remove(triple);
		}


		//aggiungo i nodi sorgente, elimino i vecchi nodi target, aggiungo i nuovi target, 
		//aggiungo i nuovi nodi e gli archi al sottografo
		for (Triple<Dimension, String, String> oldTarget : bridgeTargetToDelete) {

			navigatore.getBridgeTarget().remove(oldTarget);

			Triple<Dimension, String, String> realTarget = null;

			if(navigatore.isHelped()) {
				realTarget = new Triple<Dimension, String, String>(oldTarget.getFirst(), oldTarget.getSecond(), myId);
			}
			
			else
				realTarget = oldTarget;
			
			navigatore.getBridgeSource().add(realTarget);


			
			
			Set<MyDefaultWeightedEdge> edgesOfNewSourceNode = navigatore.getGraph().edgesOf(realTarget);

			for (MyDefaultWeightedEdge edge : edgesOfNewSourceNode) {
				Triple<Dimension, String, String> newTarget = navigatore.getGraph().getEdgeTarget(edge);

				if(!bridgeSourceToDelete.contains(newTarget) && !bridgeTargetToDelete.contains(newTarget)) {

					//aggiungo il nuovo target
					//					Triple<Dimension, String, String> target = new Triple<Dimension, String, String>(newTarget.getFirst(), newTarget.getSecond(), "1");
					navigatore.getBridgeTarget().add(newTarget);

					//aggiungo il nodo al sottografo 
					subGraph.addVertex(newTarget);

					//aggiungo l' arco al sottografo e le relative auto
					if(navigatore.getGraph().containsEdge(newTarget, realTarget)) {

						MyDefaultWeightedEdge edge2 = navigatore.getGraph().getEdge(newTarget, realTarget);

						for (int i = 0; i < edge2.getSizeListAuto(); i++) {
							for (int j = 0; j < navigatore.getBroker().getAutoBroker().size(); j++) {
								Auto auto = navigatore.getBroker().getAutoBroker().get(j);
								if(edge2.getListIdAuto().get(i) == auto.getId()) {
									navigatore.addAuto(auto);
									break;
								}

							}
						}



						subGraph.addEdge(newTarget, realTarget);
					}
				}
			}
		}

		// **************************
		if(navigatore.isHelped()) {
			for (Triple<Dimension, String, String> triple : navigatore.getBridgeSource()) {

				if(navigatore.getBridgeTarget().contains(triple))
					navigatore.getBridgeTarget().remove(triple);
						
			}
		}
	}


	private void refreshNavigatoreHelpedStructures(String idNav) {

		Subgraph<Triple<Dimension,String,String>, MyDefaultWeightedEdge, 
		Graph<Triple<Dimension,String,String>,MyDefaultWeightedEdge>> subGraph = navigatore.getSubGraph();


		//lista di nodi ex sorgenti da eliminare
		List<Triple<Dimension, String, String>> bridgeSourceToDelete  = new LinkedList<Triple<Dimension, String, String>>();

		//lista di nodi ex target da eliminare
		List<Triple<Dimension, String, String>> bridgeTargetToDelete  = new LinkedList<Triple<Dimension, String, String>>();	

		for (Triple<Dimension, String, String> oldTarget : navigatore.getBridgeTarget()) {

			if(oldTarget.getThird().equals(idNav)) {

				bridgeTargetToDelete.add(oldTarget);

				for (Triple<Dimension, String, String> oldSource : navigatore.getBridgeSource()) {

					//elimino dal sottografo il vecchio nodo target e l'arco collegato ad esso
					if(subGraph.containsEdge(oldTarget, oldSource)) {
						bridgeSourceToDelete.add(oldSource);

						MyDefaultWeightedEdge edge = subGraph.getEdge(oldTarget, oldSource);

						//rimuovo tutte le auto dal navigatore
						for (int i = 0; i < edge.getSizeListAuto(); i++) {
							navigatore.removeAuto(edge.getListIdAuto().get(i));
						}

						subGraph.removeEdge(edge);

						subGraph.removeVertex(oldTarget);
					}
				}
			}
		}

		//elimino i vecchi nodi target
		for (Triple<Dimension, String, String> triple : bridgeTargetToDelete) {
			navigatore.getBridgeTarget().remove(triple);
		}


		//aggiungo i nuovi target, rimuovo i vecchi source, setto i nuovi source
		for (Triple<Dimension, String, String> oldSource : bridgeSourceToDelete) {


			navigatore.getBridgeSource().remove(oldSource);

			Set<MyDefaultWeightedEdge> edgesOfNewTargetNode = navigatore.getGraph().edgesOf(oldSource);

			for (MyDefaultWeightedEdge edge : edgesOfNewTargetNode) {
				Triple<Dimension, String, String> newSource = navigatore.getGraph().getEdgeTarget(edge);

				if(!bridgeTargetToDelete.contains(newSource) && !bridgeSourceToDelete.contains(newSource)) {

					navigatore.getBridgeSource().add(newSource);




					//elimino primo arco dal subgraph
					if(subGraph.containsEdge(newSource, oldSource)) {

						MyDefaultWeightedEdge arco = subGraph.getEdge(newSource, oldSource);

						//rimuovo tutte le auto dal navigatore
						for (int i = 0; i < arco.getSizeListAuto(); i++) {

							navigatore.removeAuto(arco.getListIdAuto().get(i));
						}

						subGraph.removeEdge(arco);

					}
				}
			}

			Triple<Dimension, String, String> target = new Triple<Dimension, String, String>(oldSource.getFirst(), oldSource.getSecond(), idNav);
			//			navigatore.getBridgeTarget().add(oldSource);
			navigatore.getBridgeTarget().add(target);
		}

	}


	private void ripristinoNavigatoreHelped(String idNav){
		
//		Integer idNav = Integer.parseInt(myAgent.getLocalName().substring(10, myAgent.getLocalName().length()));
//		
//		navigatore.getBridgeSource().clear();
//		navigatore.getBridgeTarget().clear();
//		
//		navigatore.setBridgeSource(navigatore.getBroker().getParser().createBridgeSource(idNav));
//		navigatore.setBridgeTarget(navigatore.getBroker().getParser().createBridgeTarget(idNav));
		
		
	}
	
	//modificare i nomi dei passaggi di stato!
	@Override
	public int onEnd() {
		// TODO Auto-generated method stub

		System.out.println(myAgent.getLocalName()+"      STEP!!!!!!!!!   "+step);

		if(ciclo){

			if(navigatore.getWaitingCarsWithoutWays().size() > 0 || navigatore.getAutos().isEmpty())
				return navigatore.BARGAININGSTREET_TO_GENERATEROUTE;

			else if(navigatore.getWaitingCarsWithWays().size() > 0)
				return navigatore.BARGAININGSTREET_TO_PUTINSTREET;


			else
				return navigatore.BARGAININGSTREET_TO_UPDATE_AUTO_POSITION;
		}
		else
			return navigatore.CONTINUE_TO_BARGAININGSTREET;

	}



	@Override
	public boolean done() {

		return step == Step.EXIT;
	}


}
